home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.7 / tcpdump- / tcpdump-richard-1.7 / tcpdump-3.0 / print-decnet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-03  |  20.5 KB  |  765 lines

  1. /*
  2.  * Copyright (c) 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-decnet.c,v 1.15 94/06/20 19:44:38 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29. #include <sys/socket.h>
  30.  
  31. #include <net/if.h>
  32. #ifdef    DECNETLIB
  33. #include <netdnet/dnetdb.h>
  34. #endif
  35.  
  36. #include <ctype.h>
  37. #include <stdio.h>
  38. #include <string.h>
  39. #ifdef __STDC__
  40. #include <stdlib.h>
  41. #endif
  42. #include <unistd.h>
  43.  
  44. #include "decnet.h"
  45. #include "interface.h"
  46. #include "addrtoname.h"
  47.  
  48. /* Forwards */
  49. static void print_decnet_ctlmsg(const union routehdr *, int);
  50. static void print_t_info(int);
  51. static void print_l1_routes(const char *, int);
  52. static void print_l2_routes(const char *, int);
  53. static void print_i_info(int);
  54. static void print_elist(const char *, int);
  55. static void print_nsp(const u_char *, int);
  56. static void print_reason(int);
  57. #ifdef    PRINT_NSPDATA
  58. static void pdata(u_char *, int);
  59. #endif
  60.  
  61. #ifdef    DECNETLIB
  62. extern char *dnet_htoa(struct dn_naddr *);
  63. #endif
  64.  
  65. void
  66. decnet_print(register const u_char *ap, register int length,
  67.          register int caplen)
  68. {
  69.     static union routehdr rhcopy;
  70.     register union routehdr *rhp = &rhcopy;
  71.     register int mflags;
  72.     int dst, src, hops;
  73.     int rhlen;
  74.     const u_char *nspp;
  75.     int nsplen;
  76.     int pktlen;
  77.  
  78.     if (length < sizeof(struct shorthdr)) {
  79.         (void)printf("[|decnet]");
  80.         return;
  81.     }
  82.  
  83.     pktlen = EXTRACT_16BITS(ap);
  84.  
  85.     rhlen = min(length, caplen);
  86.     rhlen = min(rhlen, sizeof(*rhp));
  87.     bcopy(&(ap[sizeof(short)]), rhp, rhlen);
  88.  
  89.     mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
  90.  
  91.     if (mflags & RMF_PAD) {
  92.         /* pad bytes of some sort in front of message */
  93.         int padlen = mflags & RMF_PADMASK;
  94.         if (vflag)
  95.         (void) printf("[pad:%d] ", padlen);
  96.         ap += padlen;
  97.         length -= padlen;
  98.         caplen -= padlen;
  99.         rhlen = min(length, caplen);
  100.         rhlen = min(rhlen, sizeof(*rhp));
  101.         bcopy(&(ap[sizeof(short)]), rhp, rhlen);
  102.         mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
  103.     }
  104.  
  105.     if (mflags & RMF_FVER) {
  106.         (void) printf("future-version-decnet");
  107.         default_print(ap, length);
  108.         return;
  109.     }
  110.  
  111.     /* is it a control message? */
  112.     if (mflags & RMF_CTLMSG) {
  113.         print_decnet_ctlmsg(rhp, min(length, caplen));
  114.         return;
  115.     }
  116.  
  117.     switch (mflags & RMF_MASK) {
  118.     case RMF_LONG:
  119.         dst = EXTRACT_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
  120.         src = EXTRACT_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
  121.         hops = EXTRACT_8BITS(rhp->rh_long.lg_visits);
  122.         nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
  123.         nsplen = min((length - sizeof(struct longhdr)),
  124.              (caplen - sizeof(struct longhdr)));
  125.         break;
  126.     case RMF_SHORT:
  127.         dst = EXTRACT_16BITS(rhp->rh_short.sh_dst);
  128.         src = EXTRACT_16BITS(rhp->rh_short.sh_src);
  129.         hops = (EXTRACT_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
  130.         nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
  131.         nsplen = min((length - sizeof(struct shorthdr)),
  132.              (caplen - sizeof(struct shorthdr)));
  133.         break;
  134.     default:
  135.         (void) printf("unknown message flags under mask");
  136.         default_print((u_char *)ap, length);
  137.         return;
  138.     }
  139.  
  140.     (void)printf("%s > %s %d ",
  141.             dnaddr_string(src), dnaddr_string(dst), pktlen);
  142.     if (vflag) {
  143.         if (mflags & RMF_RQR)
  144.         (void)printf("RQR ");
  145.         if (mflags & RMF_RTS)
  146.         (void)printf("RTS ");
  147.         if (mflags & RMF_IE)
  148.         (void)printf("IE ");
  149.         (void)printf("%d hops ", hops);
  150.     }
  151.  
  152.     print_nsp(nspp, nsplen);
  153. }
  154.  
  155. static void
  156. print_decnet_ctlmsg(register const union routehdr *rhp, int length)
  157. {
  158.     int mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
  159.     register union controlmsg *cmp = (union controlmsg *)rhp;
  160.     int src, dst, info, blksize, eco, ueco, hello, other, vers;
  161.     etheraddr srcea, rtea;
  162.     int priority;
  163.     char *rhpx = (char *)rhp;
  164.  
  165.     switch (mflags & RMF_CTLMASK) {
  166.     case RMF_INIT:
  167.         (void)printf("init ");
  168.         src = EXTRACT_16BITS(cmp->cm_init.in_src);
  169.         info = EXTRACT_8BITS(cmp->cm_init.in_info);
  170.         blksize = EXTRACT_16BITS(cmp->cm_init.in_blksize);
  171.         vers = EXTRACT_8BITS(cmp->cm_init.in_vers);
  172.         eco = EXTRACT_8BITS(cmp->cm_init.in_eco);
  173.         ueco = EXTRACT_8BITS(cmp->cm_init.in_ueco);
  174.         hello = EXTRACT_16BITS(cmp->cm_init.in_hello);
  175.         print_t_info(info);
  176.         (void)printf(
  177.         "src %sblksize %d vers %d eco %d ueco %d hello %d",
  178.             dnaddr_string(src), blksize, vers, eco, ueco,
  179.             hello);
  180.         break;
  181.     case RMF_VER:
  182.         (void)printf("verification ");
  183.         src = EXTRACT_16BITS(cmp->cm_ver.ve_src);
  184.         other = EXTRACT_8BITS(cmp->cm_ver.ve_fcnval);
  185.         (void)printf("src %s fcnval %o", dnaddr_string(src), other);
  186.         break;
  187.     case RMF_TEST:
  188.         (void)printf("test ");
  189.         src = EXTRACT_16BITS(cmp->cm_test.te_src);
  190.         other = EXTRACT_8BITS(cmp->cm_test.te_data);
  191.         (void)printf("src %s data %o", dnaddr_string(src), other);
  192.         break;
  193.     case RMF_L1ROUT:
  194.         (void)printf("lev-1-routing ");
  195.         src = EXTRACT_16BITS(cmp->cm_l1rou.r1_src);
  196.         (void)printf("src %s ", dnaddr_string(src));
  197.         print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
  198.                 length - sizeof(struct l1rout));
  199.         break;
  200.     case RMF_L2ROUT:
  201.         (void)printf("lev-2-routing ");
  202.         src = EXTRACT_16BITS(cmp->cm_l2rout.r2_src);
  203.         (void)printf("src %s ", dnaddr_string(src));
  204.         print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
  205.                 length - sizeof(struct l2rout));
  206.         break;
  207.     case RMF_RHELLO:
  208.         (void)printf("router-hello ");
  209.         vers = EXTRACT_8BITS(cmp->cm_rhello.rh_vers);
  210.         eco = EXTRACT_8BITS(cmp->cm_rhello.rh_eco);
  211.         ueco = EXTRACT_8BITS(cmp->cm_rhello.rh_ueco);
  212.         bcopy(&(cmp->cm_rhello.rh_src), &srcea, sizeof(srcea));
  213.         src = EXTRACT_16BITS(srcea.dne_remote.dne_nodeaddr);
  214.         info = EXTRACT_8BITS(cmp->cm_rhello.rh_info);
  215.         blksize = EXTRACT_16BITS(cmp->cm_rhello.rh_blksize);
  216.         priority = EXTRACT_8BITS(cmp->cm_rhello.rh_priority);
  217.         hello = EXTRACT_16BITS(cmp->cm_rhello.rh_hello);
  218.         print_i_info(info);
  219.         (void)printf(
  220.         "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
  221.             vers, eco, ueco, dnaddr_string(src),
  222.             blksize, priority, hello);
  223.         print_elist(&(rhpx[sizeof(struct rhellomsg)]),
  224.                 length - sizeof(struct rhellomsg));
  225.         break;
  226.     case RMF_EHELLO:
  227.         (void)printf("endnode-hello ");
  228.         vers = EXTRACT_8BITS(cmp->cm_ehello.eh_vers);
  229.         eco = EXTRACT_8BITS(cmp->cm_ehello.eh_eco);
  230.         ueco = EXTRACT_8BITS(cmp->cm_ehello.eh_ueco);
  231.         bcopy(&(cmp->cm_ehello.eh_src), &srcea, sizeof(srcea));
  232.         src = EXTRACT_16BITS(srcea.dne_remote.dne_nodeaddr);
  233.         info = EXTRACT_8BITS(cmp->cm_ehello.eh_info);
  234.         blksize = EXTRACT_16BITS(cmp->cm_ehello.eh_blksize);
  235.         /*seed*/
  236.         bcopy(&(cmp->cm_ehello.eh_router), &rtea, sizeof(rtea));
  237.         dst = EXTRACT_16BITS(rtea.dne_remote.dne_nodeaddr);
  238.         hello = EXTRACT_16BITS(cmp->cm_ehello.eh_hello);
  239.         other = EXTRACT_8BITS(cmp->cm_ehello.eh_data);
  240.         print_i_info(info);
  241.         (void)printf(
  242.     "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
  243.             vers, eco, ueco, dnaddr_string(src),
  244.             blksize, dnaddr_string(dst), hello, other);
  245.         break;
  246.  
  247.     default:
  248.         (void)printf("unknown control message");
  249.         default_print((u_char *)rhp, length);
  250.         break;
  251.     }
  252. }
  253.  
  254. static void
  255. print_t_info(int info)
  256. {
  257.     int ntype = info & 3;
  258.     switch (ntype) {
  259.     case 0: (void)printf("reserved-ntype? "); break;
  260.     case TI_L2ROUT: (void)printf("l2rout "); break;
  261.     case TI_L1ROUT: (void)printf("l1rout "); break;
  262.     case TI_ENDNODE: (void)printf("endnode "); break;
  263.     }
  264.     if (info & TI_VERIF)
  265.         (void)printf("verif ");
  266.     if (info & TI_BLOCK)
  267.         (void)printf("blo ");
  268. }
  269.  
  270. static void
  271. print_l1_routes(const char *rp, int len)
  272. {
  273.     int count;
  274.     int id;
  275.     int info;
  276.  
  277.     /* The last short is a checksum */
  278.     while (len > (3 * sizeof(short))) {
  279.         count = EXTRACT_16BITS(rp);
  280.         if (count > 1024)
  281.         return;    /* seems to be bogus from here on */
  282.         rp += sizeof(short);
  283.         len -= sizeof(short);
  284.         id = EXTRACT_16BITS(rp);
  285.         rp += sizeof(short);
  286.         len -= sizeof(short);
  287.         info = EXTRACT_16BITS(rp);
  288.         rp += sizeof(short);
  289.         len -= sizeof(short);
  290.         (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
  291.                 RI_COST(info), RI_HOPS(info));
  292.     }
  293. }
  294.  
  295. static void
  296. print_l2_routes(const char *rp, int len)
  297. {
  298.     int count;
  299.     int area;
  300.     int info;
  301.  
  302.     /* The last short is a checksum */
  303.     while (len > (3 * sizeof(short))) {
  304.         count = EXTRACT_16BITS(rp);
  305.         if (count > 1024)
  306.         return;    /* seems to be bogus from here on */
  307.         rp += sizeof(short);
  308.         len -= sizeof(short);
  309.         area = EXTRACT_16BITS(rp);
  310.         rp += sizeof(short);
  311.         len -= sizeof(short);
  312.         info = EXTRACT_16BITS(rp);
  313.         rp += sizeof(short);
  314.         len -= sizeof(short);
  315.         (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
  316.                 RI_COST(info), RI_HOPS(info));
  317.     }
  318. }
  319.  
  320. static void
  321. print_i_info(int info)
  322. {
  323.     int ntype = info & II_TYPEMASK;
  324.     switch (ntype) {
  325.     case 0: (void)printf("reserved-ntype? "); break;
  326.     case II_L2ROUT: (void)printf("l2rout "); break;
  327.     case II_L1ROUT: (void)printf("l1rout "); break;
  328.     case II_ENDNODE: (void)printf("endnode "); break;
  329.     }
  330.     if (info & II_VERIF)
  331.         (void)printf("verif ");
  332.     if (info & II_NOMCAST)
  333.         (void)printf("nomcast ");
  334.     if (info & II_BLOCK)
  335.         (void)printf("blo ");
  336. }
  337.  
  338. static void
  339. print_elist(const char *elp, int len)
  340. {
  341.     /* Not enough examples available for me to debug this */
  342. }
  343.  
  344. static void
  345. print_nsp(const u_char *nspp, int nsplen)
  346. {
  347.     const struct nsphdr *nsphp = (struct nsphdr *)nspp;
  348.     int dst, src, flags;
  349.  
  350.     flags = EXTRACT_8BITS(nsphp->nh_flags);
  351.     dst = EXTRACT_16BITS(nsphp->nh_dst);
  352.     src = EXTRACT_16BITS(nsphp->nh_src);
  353.  
  354.     switch (flags & NSP_TYPEMASK) {
  355.     case MFT_DATA:
  356.         switch (flags & NSP_SUBMASK) {
  357.         case MFS_BOM:
  358.         case MFS_MOM:
  359.         case MFS_EOM:
  360.         case MFS_BOM+MFS_EOM:
  361.         printf("data %d>%d ", src, dst);
  362.         {
  363.             struct seghdr *shp = (struct seghdr *)nspp;
  364.             int ack;
  365. #ifdef    PRINT_NSPDATA
  366.             u_char *dp;
  367. #endif
  368.             int data_off = sizeof(struct minseghdr);
  369.  
  370.             ack = EXTRACT_16BITS(shp->sh_seq[0]);
  371.             if (ack & SGQ_ACK) {    /* acknum field */
  372.             if ((ack & SGQ_NAK) == SGQ_NAK)
  373.                 (void)printf("nak %d ", ack & SGQ_MASK);
  374.             else
  375.                 (void)printf("ack %d ", ack & SGQ_MASK);
  376.                 ack = EXTRACT_16BITS(shp->sh_seq[1]);
  377.             data_off += sizeof(short);
  378.             if (ack & SGQ_OACK) {    /* ackoth field */
  379.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  380.                 (void)printf("onak %d ", ack & SGQ_MASK);
  381.                 else
  382.                 (void)printf("oack %d ", ack & SGQ_MASK);
  383.                 ack = EXTRACT_16BITS(shp->sh_seq[2]);
  384.                 data_off += sizeof(short);
  385.             }
  386.             }
  387.             (void)printf("seg %d ", ack & SGQ_MASK);
  388. #ifdef    PRINT_NSPDATA
  389.             dp = &(nspp[data_off]);
  390.             pdata(dp, 10);
  391. #endif
  392.         }
  393.         break;
  394.         case MFS_ILS+MFS_INT:
  395.         printf("intr ");
  396.         {
  397.             struct seghdr *shp = (struct seghdr *)nspp;
  398.             int ack;
  399. #ifdef    PRINT_NSPDATA
  400.             u_char *dp;
  401. #endif
  402.             int data_off = sizeof(struct minseghdr);
  403.  
  404.             ack = EXTRACT_16BITS(shp->sh_seq[0]);
  405.             if (ack & SGQ_ACK) {    /* acknum field */
  406.             if ((ack & SGQ_NAK) == SGQ_NAK)
  407.                 (void)printf("nak %d ", ack & SGQ_MASK);
  408.             else
  409.                 (void)printf("ack %d ", ack & SGQ_MASK);
  410.                 ack = EXTRACT_16BITS(shp->sh_seq[1]);
  411.             data_off += sizeof(short);
  412.             if (ack & SGQ_OACK) {    /* ackdat field */
  413.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  414.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  415.                 else
  416.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  417.                 ack = EXTRACT_16BITS(shp->sh_seq[2]);
  418.                 data_off += sizeof(short);
  419.             }
  420.             }
  421.             (void)printf("seg %d ", ack & SGQ_MASK);
  422. #ifdef    PRINT_NSPDATA
  423.             dp = &(nspp[data_off]);
  424.             pdata(dp, 10);
  425. #endif
  426.         }
  427.         break;
  428.         case MFS_ILS:
  429.         (void)printf("link-service %d>%d ", src, dst);
  430.         {
  431.             struct seghdr *shp = (struct seghdr *)nspp;
  432.             struct lsmsg *lsmp =
  433.             (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
  434.             int ack;
  435.             int lsflags, fcval;
  436.  
  437.             ack = EXTRACT_16BITS(shp->sh_seq[0]);
  438.             if (ack & SGQ_ACK) {    /* acknum field */
  439.             if ((ack & SGQ_NAK) == SGQ_NAK)
  440.                 (void)printf("nak %d ", ack & SGQ_MASK);
  441.             else
  442.                 (void)printf("ack %d ", ack & SGQ_MASK);
  443.                 ack = EXTRACT_16BITS(shp->sh_seq[1]);
  444.             if (ack & SGQ_OACK) {    /* ackdat field */
  445.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  446.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  447.                 else
  448.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  449.                 ack = EXTRACT_16BITS(shp->sh_seq[2]);
  450.             }
  451.             }
  452.             (void)printf("seg %d ", ack & SGQ_MASK);
  453.             lsflags = EXTRACT_8BITS(lsmp->ls_lsflags);
  454.             fcval = EXTRACT_8BITS(lsmp->ls_fcval);
  455.             switch (lsflags & LSI_MASK) {
  456.             case LSI_DATA:
  457.             (void)printf("dat seg count %d ", fcval);
  458.             switch (lsflags & LSM_MASK) {
  459.             case LSM_NOCHANGE:
  460.                 break;
  461.             case LSM_DONOTSEND:
  462.                 (void)printf("donotsend-data ");
  463.                 break;
  464.             case LSM_SEND:
  465.                 (void)printf("send-data ");
  466.                 break;
  467.             default:
  468.                 (void)printf("reserved-fcmod? %x", lsflags);
  469.                 break;
  470.             }
  471.             break;
  472.             case LSI_INTR:
  473.             (void)printf("intr req count %d ", fcval);
  474.             break;
  475.             default:
  476.             (void)printf("reserved-fcval-int? %x", lsflags);
  477.             break;
  478.             }
  479.         }
  480.         break;
  481.         default:
  482.         (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
  483.         break;
  484.         }
  485.         break;
  486.     case MFT_ACK:
  487.         switch (flags & NSP_SUBMASK) {
  488.         case MFS_DACK:
  489.         (void)printf("data-ack %d>%d ", src, dst);
  490.         {
  491.             struct ackmsg *amp = (struct ackmsg *)nspp;
  492.             int ack;
  493.  
  494.             ack = EXTRACT_16BITS(amp->ak_acknum[0]);
  495.             if (ack & SGQ_ACK) {    /* acknum field */
  496.             if ((ack & SGQ_NAK) == SGQ_NAK)
  497.                 (void)printf("nak %d ", ack & SGQ_MASK);
  498.             else
  499.                 (void)printf("ack %d ", ack & SGQ_MASK);
  500.                 ack = EXTRACT_16BITS(amp->ak_acknum[1]);
  501.             if (ack & SGQ_OACK) {    /* ackoth field */
  502.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  503.                 (void)printf("onak %d ", ack & SGQ_MASK);
  504.                 else
  505.                 (void)printf("oack %d ", ack & SGQ_MASK);
  506.             }
  507.             }
  508.         }
  509.         break;
  510.         case MFS_IACK:
  511.         (void)printf("ils-ack %d>%d ", src, dst);
  512.         {
  513.             struct ackmsg *amp = (struct ackmsg *)nspp;
  514.             int ack;
  515.  
  516.             ack = EXTRACT_16BITS(amp->ak_acknum[0]);
  517.             if (ack & SGQ_ACK) {    /* acknum field */
  518.             if ((ack & SGQ_NAK) == SGQ_NAK)
  519.                 (void)printf("nak %d ", ack & SGQ_MASK);
  520.             else
  521.                 (void)printf("ack %d ", ack & SGQ_MASK);
  522.                 ack = EXTRACT_16BITS(amp->ak_acknum[1]);
  523.             if (ack & SGQ_OACK) {    /* ackdat field */
  524.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  525.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  526.                 else
  527.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  528.             }
  529.             }
  530.         }
  531.         break;
  532.         case MFS_CACK:
  533.         (void)printf("conn-ack %d", dst);
  534.         break;
  535.         default:
  536.         (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
  537.         break;
  538.         }
  539.         break;
  540.     case MFT_CTL:
  541.         switch (flags & NSP_SUBMASK) {
  542.         case MFS_CI:
  543.         case MFS_RCI:
  544.         if ((flags & NSP_SUBMASK) == MFS_CI)
  545.             (void)printf("conn-initiate ");
  546.         else
  547.             (void)printf("retrans-conn-initiate ");
  548.         (void)printf("%d>%d ", src, dst);
  549.         {
  550.             struct cimsg *cimp = (struct cimsg *)nspp;
  551.             int services, info, segsize;
  552. #ifdef    PRINT_NSPDATA
  553.             u_char *dp;
  554. #endif
  555.  
  556.             services = EXTRACT_8BITS(cimp->ci_services);
  557.             info = EXTRACT_8BITS(cimp->ci_info);
  558.             segsize = EXTRACT_16BITS(cimp->ci_segsize);
  559.  
  560.             switch (services & COS_MASK) {
  561.             case COS_NONE:
  562.             break;
  563.             case COS_SEGMENT:
  564.             (void)printf("seg ");
  565.             break;
  566.             case COS_MESSAGE:
  567.             (void)printf("msg ");
  568.             break;
  569.             case COS_CRYPTSER:
  570.             (void)printf("crypt ");
  571.             break;
  572.             }
  573.             switch (info & COI_MASK) {
  574.             case COI_32:
  575.             (void)printf("ver 3.2 ");
  576.             break;
  577.             case COI_31:
  578.             (void)printf("ver 3.1 ");
  579.             break;
  580.             case COI_40:
  581.             (void)printf("ver 4.0 ");
  582.             break;
  583.             case COI_41:
  584.             (void)printf("ver 4.1 ");
  585.             break;
  586.             }
  587.             (void)printf("segsize %d ", segsize);
  588. #ifdef    PRINT_NSPDATA
  589.             dp = &(nspp[sizeof(struct cimsg)]);
  590.             pdata(dp, nsplen - sizeof(struct cimsg));
  591. #endif
  592.         }
  593.         break;
  594.         case MFS_CC:
  595.         (void)printf("conn-confirm %d>%d ", src, dst);
  596.         {
  597.             struct ccmsg *ccmp = (struct ccmsg *)nspp;
  598.             int services, info, segsize, optlen;
  599. #ifdef    PRINT_NSPDATA
  600.             u_char *dp;
  601. #endif
  602.  
  603.             services = EXTRACT_8BITS(ccmp->cc_services);
  604.             info = EXTRACT_8BITS(ccmp->cc_info);
  605.             segsize = EXTRACT_16BITS(ccmp->cc_segsize);
  606.             optlen = EXTRACT_8BITS(ccmp->cc_optlen);
  607.  
  608.             switch (services & COS_MASK) {
  609.             case COS_NONE:
  610.             break;
  611.             case COS_SEGMENT:
  612.             (void)printf("seg ");
  613.             break;
  614.             case COS_MESSAGE:
  615.             (void)printf("msg ");
  616.             break;
  617.             case COS_CRYPTSER:
  618.             (void)printf("crypt ");
  619.             break;
  620.             }
  621.             switch (info & COI_MASK) {
  622.             case COI_32:
  623.             (void)printf("ver 3.2 ");
  624.             break;
  625.             case COI_31:
  626.             (void)printf("ver 3.1 ");
  627.             break;
  628.             case COI_40:
  629.             (void)printf("ver 4.0 ");
  630.             break;
  631.             case COI_41:
  632.             (void)printf("ver 4.1 ");
  633.             break;
  634.             }
  635.             (void)printf("segsize %d ", segsize);
  636.             if (optlen) {
  637.             (void)printf("optlen %d ", optlen);
  638. #ifdef    PRINT_NSPDATA
  639.             optlen = min(optlen, nsplen - sizeof(struct ccmsg));
  640.             dp = &(nspp[sizeof(struct ccmsg)]);
  641.             pdata(dp, optlen);
  642. #endif
  643.             }
  644.         }
  645.         break;
  646.         case MFS_DI:
  647.         (void)printf("disconn-initiate %d>%d ", src, dst);
  648.         {
  649.             struct dimsg *dimp = (struct dimsg *)nspp;
  650.             int reason, optlen;
  651. #ifdef    PRINT_NSPDATA
  652.             u_char *dp;
  653. #endif
  654.  
  655.             reason = EXTRACT_16BITS(dimp->di_reason);
  656.             optlen = EXTRACT_8BITS(dimp->di_optlen);
  657.  
  658.             print_reason(reason);
  659.             if (optlen) {
  660.             (void)printf("optlen %d ", optlen);
  661. #ifdef    PRINT_NSPDATA
  662.             optlen = min(optlen, nsplen - sizeof(struct dimsg));
  663.             dp = &(nspp[sizeof(struct dimsg)]);
  664.             pdata(dp, optlen);
  665. #endif
  666.             }
  667.         }
  668.         break;
  669.         case MFS_DC:
  670.         (void)printf("disconn-confirm %d>%d ", src, dst);
  671.         {
  672.             struct dcmsg *dcmp = (struct dcmsg *)nspp;
  673.             int reason;
  674.  
  675.             reason = EXTRACT_16BITS(dcmp->dc_reason);
  676.  
  677.             print_reason(reason);
  678.         }
  679.         break;
  680.         default:
  681.         (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
  682.         break;
  683.         }
  684.         break;
  685.     default:
  686.         (void)printf("reserved-type? %x %d > %d", flags, src, dst);
  687.         break;
  688.     }
  689. }
  690.  
  691. struct token reason2str[] = {
  692.     { UC_OBJREJECT,        "object rejected connect" },
  693.     { UC_RESOURCES,        "insufficient resources" },
  694.     { UC_NOSUCHNODE,    "unrecognized node name" },
  695.     { DI_SHUT,        "node is shutting down" },
  696.     { UC_NOSUCHOBJ,        "unrecognized object" },
  697.     { UC_INVOBJFORMAT,    "invalid object name format" },
  698.     { UC_OBJTOOBUSY,    "object too busy" },
  699.     { DI_PROTOCOL,        "protocol error discovered" },
  700.     { DI_TPA,        "third party abort" },
  701.     { UC_USERABORT,        "user abort" },
  702.     { UC_INVNODEFORMAT,    "invalid node name format" },
  703.     { UC_LOCALSHUT,        "local node shutting down" },
  704.     { DI_LOCALRESRC,    "insufficient local resources" },
  705.     { DI_REMUSERRESRC,    "insufficient remote user resources" },
  706.     { UC_ACCESSREJECT,    "invalid access control information" },
  707.     { DI_BADACCNT,        "bad ACCOUNT information" },
  708.     { UC_NORESPONSE,    "no response from object" },
  709.     { UC_UNREACHABLE,    "node unreachable" },
  710.     { DC_NOLINK,        "no link terminate" },
  711.     { DC_COMPLETE,        "disconnect complete" },
  712.     { DI_BADIMAGE,        "bad image data in connect" },
  713.     { DI_SERVMISMATCH,    "cryptographic service mismatch" },
  714.     { 0,            NULL }
  715. };
  716.  
  717. static void
  718. print_reason(register int reason)
  719. {
  720.     printf("%s ", tok2str(reason2str, "reason-%d", reason));
  721. }
  722.  
  723. char *
  724. dnnum_string(u_short dnaddr)
  725. {
  726.     char *str;
  727.     int area = (dnaddr & AREAMASK) >> AREASHIFT;
  728.     int node = dnaddr & NODEMASK;
  729.  
  730.     str = (char *)malloc(sizeof("00.0000"));
  731.     sprintf(str, "%d.%d", area, node);
  732.     return(str);
  733. }
  734.  
  735. char *
  736. dnname_string(u_short dnaddr)
  737. {
  738. #ifdef    DECNETLIB
  739.     struct dn_naddr dna;
  740.  
  741.     dna.a_len = sizeof(short);
  742.     bcopy((char *)&dnaddr, dna.a_addr, sizeof(short));
  743.     return (savestr(dnet_htoa(&dna)));
  744. #else
  745.     return(dnnum_string(dnaddr));    /* punt */
  746. #endif
  747. }
  748.  
  749. #ifdef    PRINT_NSPDATA
  750. static void
  751. pdata(u_char *dp, int maxlen)
  752. {
  753.     char c;
  754.     int x = maxlen;
  755.  
  756.     while (x-- > 0) {
  757.         c = *dp++;
  758.         if (isprint(c))
  759.         putchar(c);
  760.         else
  761.         printf("\\%o", c & 0xFF);
  762.     }
  763. }
  764. #endif
  765.